const Message = require('../models/message');
const User = require('../models/user');

/**
 * 消息服务
 * 处理消息相关的业务逻辑
 */
class MessageService {
  /**
   * 创建消息
   * @param {Object} messageData - 消息数据
   * @param {ObjectId} senderId - 发送者ID
   * @returns {Promise<Message>} - 创建的消息
   */
  static async createMessage(messageData, senderId) {
    try {
      // 获取发送者信息
      const sender = await User.findById(senderId);
      if (!sender) {
        throw new Error('发送者不存在');
      }
      
      // 创建消息
      const message = new Message({
        ...messageData,
        sender: senderId,
        senderName: sender.username,
        senderRole: sender.role,
        status: 'pending',
        read: false
      });
      
      await message.save();
      return message;
    } catch (error) {
      throw new Error(`创建消息失败: ${error.message}`);
    }
  }
  
  /**
   * 获取消息列表
   * @param {Object} filters - 过滤条件
   * @param {number} page - 页码
   * @param {number} limit - 每页数量
   * @returns {Promise<Object>} - 消息列表和分页信息
   */
  static async getMessages(filters = {}, page = 1, limit = 20) {
    try {
      // 构建查询条件
      const query = {};
      
      // 添加过滤条件
      if (filters.receiverId) {
        query.receiver = filters.receiverId;
      }
      
      if (filters.senderId) {
        query.sender = filters.senderId;
      }
      
      if (filters.type) {
        query.type = filters.type;
      }
      
      if (filters.status) {
        query.status = filters.status;
      }
      
      if (filters.read !== undefined) {
        query.read = filters.read;
      }
      
      if (filters.startDate && filters.endDate) {
        query.createdAt = {
          $gte: new Date(filters.startDate),
          $lte: new Date(filters.endDate)
        };
      }
      
      // 计算总数
      const total = await Message.countDocuments(query);
      
      // 获取分页数据
      const messages = await Message.find(query)
        .sort({ createdAt: -1 })
        .skip((page - 1) * limit)
        .limit(limit)
        .populate('sender', 'username role avatar')
        .populate('receiver', 'username role avatar')
        .lean();
      
      return {
        messages,
        pagination: {
          total,
          page,
          limit,
          totalPages: Math.ceil(total / limit)
        }
      };
    } catch (error) {
      throw new Error(`获取消息列表失败: ${error.message}`);
    }
  }
  
  /**
   * 获取消息详情
   * @param {string} messageId - 消息ID
   * @returns {Promise<Message>} - 消息详情
   */
  static async getMessageById(messageId) {
    try {
      const message = await Message.findById(messageId)
        .populate('sender', 'username role avatar')
        .populate('receiver', 'username role avatar')
        .lean();
      
      if (!message) {
        throw new Error('消息不存在');
      }
      
      return message;
    } catch (error) {
      throw new Error(`获取消息详情失败: ${error.message}`);
    }
  }
  
  /**
   * 更新消息
   * @param {string} messageId - 消息ID
   * @param {Object} updateData - 更新数据
   * @param {ObjectId} userId - 操作用户ID
   * @returns {Promise<Message>} - 更新后的消息
   */
  static async updateMessage(messageId, updateData, userId) {
    try {
      // 获取消息
      const message = await Message.findById(messageId);
      if (!message) {
        throw new Error('消息不存在');
      }
      
      // 检查权限（只有发送者或管理员可以更新）
      if (message.sender.toString() !== userId.toString()) {
        const user = await User.findById(userId);
        if (user.role !== 'admin') {
          throw new Error('无权限更新此消息');
        }
      }
      
      // 更新消息
      const updatedMessage = await Message.findByIdAndUpdate(
        messageId,
        updateData,
        { new: true, runValidators: true }
      ).lean();
      
      return updatedMessage;
    } catch (error) {
      throw new Error(`更新消息失败: ${error.message}`);
    }
  }
  
  /**
   * 删除消息
   * @param {string} messageId - 消息ID
   * @param {ObjectId} userId - 操作用户ID
   * @returns {Promise<boolean>} - 是否删除成功
   */
  static async deleteMessage(messageId, userId) {
    try {
      // 获取消息
      const message = await Message.findById(messageId);
      if (!message) {
        throw new Error('消息不存在');
      }
      
      // 检查权限（只有发送者或管理员可以删除）
      if (message.sender.toString() !== userId.toString()) {
        const user = await User.findById(userId);
        if (user.role !== 'admin') {
          throw new Error('无权限删除此消息');
        }
      }
      
      // 删除消息
      await Message.findByIdAndDelete(messageId);
      return true;
    } catch (error) {
      throw new Error(`删除消息失败: ${error.message}`);
    }
  }
  
  /**
   * 标记消息为已读
   * @param {string} messageId - 消息ID
   * @param {ObjectId} userId - 操作用户ID（接收者）
   * @returns {Promise<Message>} - 更新后的消息
   */
  static async markAsRead(messageId, userId) {
    try {
      const message = await Message.findOneAndUpdate(
        { _id: messageId, receiver: userId },
        { read: true, readAt: new Date() },
        { new: true }
      ).lean();
      
      if (!message) {
        throw new Error('消息不存在或无权限操作');
      }
      
      return message;
    } catch (error) {
      throw new Error(`标记消息失败: ${error.message}`);
    }
  }
  
  /**
   * 获取未读消息数量
   * @param {ObjectId} userId - 用户ID（接收者）
   * @returns {Promise<number>} - 未读消息数量
   */
  static async getUnreadCount(userId) {
    try {
      const count = await Message.countDocuments({
        receiver: userId,
        read: false
      });
      return count;
    } catch (error) {
      throw new Error(`获取未读消息数量失败: ${error.message}`);
    }
  }
}

module.exports = MessageService;